package cn.com.bluemoon.daps.system.service.impl;

import cn.com.bluemoon.daps.common.domain.UserInfoHolder;
import cn.com.bluemoon.daps.common.exception.DapThrowException;
import cn.com.bluemoon.daps.system.dto.SysRoleDto;
import cn.com.bluemoon.daps.system.dto.SysPageDto;
import cn.com.bluemoon.daps.system.entity.DapSysRole;
import cn.com.bluemoon.daps.system.entity.DapSysRoleMenu;
import cn.com.bluemoon.daps.system.enums.IsUseType;
import cn.com.bluemoon.daps.system.mapper.DapSysRoleMapper;
import cn.com.bluemoon.daps.system.service.DapSysRoleMenuService;
import cn.com.bluemoon.daps.system.service.DapSysRoleService;
import cn.com.bluemoon.daps.system.service.DapSysUserRoleService;
import cn.com.bluemoon.daps.system.vo.DapSysRoleVo;
import cn.com.bluemoon.daps.system.vo.SysRoleVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2022-12-19
 */
@Slf4j
@Service
public class DapSysRoleServiceImpl extends ServiceImpl<DapSysRoleMapper, DapSysRole>
        implements DapSysRoleService {

    @Autowired
    private DapSysRoleMenuService sysRoleMenuService;

    @Autowired
    private DapSysUserRoleService sysUserRoleService;

    @Override
    public IPage<DapSysRole> rolePage(SysPageDto pageDto) {
        LambdaQueryWrapper<DapSysRole> wrapper = new LambdaQueryWrapper<>();
        if(Objects.nonNull(pageDto.getIsUse())){
            wrapper.eq(DapSysRole::getIsUse,pageDto.getIsUse());
        }
        if(StringUtils.isNotEmpty(pageDto.getKey())){
            wrapper.and(w -> w.like(DapSysRole::getName, pageDto.getKey())
                    .or().like(DapSysRole::getRemarks, pageDto.getKey()));
        }
        wrapper.orderByDesc(DapSysRole::getUpdateTime);
        Page<DapSysRole> page = new Page<>(pageDto.getPageNum(), pageDto.getPageSize());
        return this.getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public SysRoleVo getRoleById(Long id){
        DapSysRole sysRole = this.getById(id);
        if(Objects.isNull(sysRole)){
            throw new DapThrowException("该角色已不存在！");
        }

        SysRoleVo sysRoleVo = new SysRoleVo();
        BeanUtils.copyProperties(sysRole,sysRoleVo);

        LambdaQueryWrapper<DapSysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DapSysRoleMenu::getRoleId,id);
        List<DapSysRoleMenu> roleMenuList = sysRoleMenuService.list(wrapper);
        if(!CollectionUtils.isEmpty(roleMenuList)){
            List<Long> list = roleMenuList.stream().map(DapSysRoleMenu::getMenuId).collect(Collectors.toList());
            sysRoleVo.setMenuIdList(list);
        }
        return sysRoleVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveRole(SysRoleDto roleDto){
        Long roleId = roleDto.getId();
        LambdaQueryWrapper<DapSysRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(DapSysRole::getName,roleDto.getName());
        if(Objects.nonNull(roleId)){
            roleWrapper.ne(DapSysRole::getId,roleId);
        }
        int count = this.count(roleWrapper);
        if(count>0){
            throw new DapThrowException("已存在名称["+roleDto.getName()+"]的角色！");
        }

        //1.保存角色
        String account = UserInfoHolder.getAccount();
        LocalDateTime now = LocalDateTime.now();
        DapSysRole sysRole = new DapSysRole();
        BeanUtils.copyProperties(roleDto,sysRole);
        if(Objects.isNull(roleId)){
            sysRole.setCreateUserId(account);
            sysRole.setCreateTime(now);
        }else {
            //先删
            sysRoleMenuService.deleteByRoleId(roleDto.getId());
        }
        sysRole.setUpdateUserId(account);
        sysRole.setUpdateTime(now);
        this.saveOrUpdate(sysRole);
        roleId = sysRole.getId();

        //2.添加角色菜单关联信息
        List<Long> menuIdList = roleDto.getMenuIdList();
        if(!CollectionUtils.isEmpty(menuIdList)){
            sysRoleMenuService.batchSave(roleId,menuIdList);
        }

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteRole(Long id){
        //1.删除角色
        this.removeById(id);

        //2.删除角色菜单关系
        sysRoleMenuService.deleteByRoleId(id);

        //3.删除用户角色关系
        sysUserRoleService.deleteByRoleId(id);

        return true;
    }

    @Override
    public List<DapSysRoleVo> getRoleVoList(){
        LambdaQueryWrapper<DapSysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DapSysRole::getIsUse, IsUseType.ENABLE.getCode());
        wrapper.orderByAsc(DapSysRole::getName);
        List<DapSysRole> sysRoleList = this.list(wrapper);
        List<DapSysRoleVo> roleVoList = sysRoleList.stream().map(r -> {
            DapSysRoleVo vo = new DapSysRoleVo();
            BeanUtils.copyProperties(r, vo);
            return vo;
        }).collect(Collectors.toList());
        return roleVoList;
    }

}
